#ifndef __MOD_ICMP4__
#define __MOD_ICMP4__

#include "decoder.hpp"

//==========================================================
class Icmp4Session : public Session
{
public:
};

//==========================================================
class Icmp4SessionRoot : public SessionRoot
{
public:
  PTree<Session> ssn;
};

//==========================================================
class Icmp4Filter : public NDecFilter 
{
  friend class Icmp4Decoder ;

private:
  u_int8_t itype, icode;
  
  enum FilterType
    {
      FT_TYPE,
      FT_CODE,
    } type;

  void check (NDecResult &res);

public:
  Icmp4Filter (FilterType t) : itype (0), icode (0), type (t) 
  {
    if (t == FT_TYPE || t == FT_CODE)
      this->setResultType (RT_INT);
  }
  ~Icmp4Filter () {}

  bool setup (string &arg);
};

//==========================================================
class Icmp4MpxFilter : public NDecMpxFilter 
{
public:
  enum FilterType
    {
      FT_NULL = 0,
      FT_SRC_PORT,
      FT_DST_PORT,
    } type;

  Icmp4MpxFilter (FilterType argType) : type (argType) {}
  ~Icmp4MpxFilter () {}
  bool setup (string &name, void * p);
  int exec (NDecResult &res);
  void * getResult (int idx);
  
private:
  PTree<NDecMpxRes> portTable;
};

//==========================================================
class Icmp4Record : public Record
{
public:
  Icmp4Record () : sport (0), dport (0) {} ;
  u_int16_t sport, dport;
};

//==========================================================
class Icmp4Decoder : public Decoder
{
private:
  static const int SSN_TIMEOUT = 600;
  static const bool DEBUG = true;
  Icmp4Record rec;

public:
  Icmp4Decoder () {};
  ~Icmp4Decoder () {};
  
  Record * decode (Packet &pkt, Record &prev);
  Icmp4Session * fetchIcmp4Session (Record &prev, u_int16_t &sport, u_int16_t &dport);
  NDecFilter * makeFilter (string &name);
};

#endif /* __MOD_ICMP4__ */
